<?php
/**
 * Ebx Lib, author Yuri(oberset)Oberukhtin, oberset@gmail.com
 */

class Ebx_Project_Tools {

	const SPLIT = '_';

	/**
	 * @static
	 * @param  $arParams
 	 * @return array
	 *
	 * return normalized filter for GetList (key => value)
	 *
	 * $arParams = array(
	 * 	array(
	 * 		'value' => filter value,
	 * 		'var' 	=> key name for search in $_GET ,$_POST,$_COOKIE
	 * 		'from'  => if value is null, search var in global arrays(get, post, session, cookie)
	 * 		'type 	=> convert valut to spec. type
	 * 		'default' => if value is null, this default value returns,
	 * 		'required' => value has been not empty
	 *  ),
	 *  ...
	 * );
	 */
	static function getFilter($arParams) {
		$result = array();

		foreach ($arParams as $field => $params) {
			if (is_int($field)) {
				if (isset($params['field'])) {
					$field = $params['field'];
					unset($params['field']);
				} else {
					continue;
				}
			}

			if ($field == 'PROPERTIES') {
				$result[$field] = self::getFilter($params);
				continue;
			}

			//standard filter
			if (!is_array($params)) {
				$result[$field] = $params;
				continue;
			}

			$value = isset($params['value']) ? $params['value'] : null;

			if ($value === null && !empty($params['var'])) {
				if (!empty($params['from'])) {
					$var = (string)$params['var'];
					$vars = array(
						'get' => '_GET',
						'post' => '_POST',
						'session' => '_SESSION',
						'cookie' => '_COOKIE'
					);

					foreach ((array)$params['from'] as $from) {
						if ($from == 'context' && null !== $value) {
							break;
						}
						if (isset($vars[$from])) {
							$value = Ebx_Http_Request::getInstance()->getParam($var, $vars[$from]);
							if (null !== $value) {
								break;
							}
						}
					}
				}
			}

			//enum значений
			if ($value !== null) {
				if (isset($params['enum'])) {
					if (!in_array($value, (array)$params['enum'])) {
						$value = null;
					}
				}

				if (isset($params['between'])) {
					$params['between'] = (array)$params['between'];
					if (
						($value < $params['between'][0]) ||
						(isset($params['between'][1]) && $value > $params['between'][1])
					) {
						$value = null;
					}
				}
			}
			
			if ($value === null) {
				if (isset($params['default'])) {
					$value = $params['default'];
				}
			}

			if (!empty($params['type'])) {
				switch ($params['type']) {
					case 'int':
					case 'integer':
						$value = (int)$value;
					break;

					case 'string':
					case 'str':
						$value = (string)$value;
					break;

					case 'date':
					case 'date_short':
					case 'date_full':
					    //format short or long
						$format = $params['type'] == 'date_full' ? 'FULL' : 'SHORT';

						//integer timestamp
						if ((string)$value === date('U', (int)$value)) {
							$value = ConvertTimeStamp((int)$value, $format, SITE_ID);
						}
						//convert long to short
						elseif ($format == 'SHORT') {
							$check = preg_replace("/[^0-9]+/", "", $value);
							//check if value contains a long format
							if (strlen($check) > 8) {
								$fromFormat = CSite::GetDateFormat('FULL');
								$toFormat = CSite::GetDateFormat($format);
								$value = CDatabase::FormatDate($value, $fromFormat, $toFormat);
							}
						}
					break;

					case 'bool':
					case 'boolean':
						if (!is_string($value) || $value != 'Y' && $value != 'N') {
							$value = $value ? 'Y' : 'N';
						}
					break;
				}
			}

			if (!empty($params['by_value'])) {
				$field .= '_VALUE';
			}
			$result[$field] = $value;
		}

		return $result;
	}

	/**
	 * @static
	 * @param  string|array $name
	 * @param  string $prefix
	 * @param  string $separator
 	 * @return string|array
	 *
	 * Split string by prefix and return first part of string
	 * $string = Ebx_Project_Tools::stripPrefix('property_code', 'property')
	 * //$string = 'code'
	 *
	 */
	static function stripPrefix($name, $prefix = null, $separator = null) {
		if (!$prefix) {
			return $name;
		}
		if (is_string($name)) {
			$prefix .= ($separator ? $separator : self::SPLIT);
			$parts = explode($prefix, $name);
			if (is_array($parts)) {
				return array_pop($parts);
			}
		} elseif (is_array($name)) {
			do  {
				$name[key($name)] = self::stripPrefix(current($name), $prefix, $separator);
			} while (false !== next($name));
		}
		return $name;
	}

	/**
	 * @static
	 * @param  string|array $name
	 * @param  string $prefix
	 * @param  string $separator
 	 * @return string|array
	 *
	 * add prefix to string.
	 * $string = Ebx_Project_Tools::addPrefix('code', 'property')
	 * //$string = property_code
	 */
	static function addPrefix($name, $prefix = null, $separator = null) {
		if (is_string($name)) {
			$name = $prefix ? (string)$prefix.($separator ? $separator : self::SPLIT).$name : $name;
		} elseif (is_array($name)) {
			do  {
				$name[key($name)] = self::addPrefix(current($name), $prefix, $separator);
			} while (false !== next($name));
		}
		return $name;
	}

	/**
	 * @static
	 * @param  $array
	 * @return array
	 *
	 * delete empty values from array
	 */
	static function clearEmpty(&$array) {
		foreach ($array as $key => $value) {
			if (is_array($value)) {
				$result[$key] = self::clearEmpty($value);
			} elseif ($value || $value === 0) {
				continue;
			}
			unset($array[$key]);
		}
	}

	/**
	 * @static
	 * @param  $array
	 * @param  string $key
	 * @param  string|array $valueKeys
	 * @return array
	 *
	 * $ar = array(
	 *  	array('ID' => 10, 'VALUE' => 100),
	 *  	array('ID' => 20, 'VALUE' => 200),
	 * );
	 *
	 * $ar = Ebx_Project_Tools::transformArray($ar, 'ID', 'VALUE');
	 * print_r($ar);
	 * //$ar = array(10 => 100, 20 => 200)
	 */
	static function transformArray($array, $key = null, $valueKeys = null) {
		$result = array();
		foreach ($array as $k => $item) {
			if ($valueKeys !== null) {
				$value = is_string($valueKeys) ? $item[$valueKeys] : array_intersect_key($item, $valueKeys);
			} else {
				$value = $item;
			}
			if ($key !== null && isset($item[$key])) {
				$result[$item[$key]] = $value;
			} else {
				$result[$k] = $value;
			}
		}
		return $result;
	}

	/**
	 * @static
	 * @param  $value
	 * @return boolean
	 *
	 * transform string like 'Y' or 'N' to boolean
	 */
	static function toBool($value) {
		if (is_bool($value)) {
			return $value;
		}

		if (is_string($value)) {
			return $value == 'Y' ? true : false;
		}
		return (bool)$value;
	}

	/**
	 * @static
	 * @param  $value
	 * @return boolean|string
	 *
	 * transform bool or int to string 'Y' or 'N'
	 */
	static function toStr($value) {
		if (is_string($value)) {
			return $value;
		} else {
			$value = (bool)$value;
		}
		return $value ? 'Y' : 'N';
	}

	static function getPropertyField($name, $value = false) {
		if (preg_match("/([<>\=\!]+)(.*)/", $name, $match)) {
			$name = $match[1].'PROPERTY_'.$match[2].($value ? '_VALUE' : '');
		} else {
			$name = 'PROPERTY_'.$name.($value ? '_VALUE' : '');
		}
		return $name;
	}

	static function getPropertyFields($array, $value) {
		return array_map(array(__CLASS__, 'getPropertyField'), $array, array($value));
	}

	static function toArrayNotation($array) {
		foreach ((array)$array as $key => $value) {
			if (false !== strpos($key, 'PROPERTY_')) {
				$tmp = explode('_', $key);
				$field = array_pop($tmp);
				$code = array_pop($tmp);
				$array['PROPERTIES'][$code][$field] = $value;
				unset($array[$key]);
			}
		}
		return $array;
	}

	/**
	 * @static
	 * @param  array $array
	 * @param  string $url
	 * @return string
	 *
	 * return relative formatted url
	 *
	 * $ar = array('ID' => 100, 'IBLOCK_ID' => 10);
	 * $url =  Ebx_Project_Tools::getUrl($ar, '/folder/page/#IBLOCK_ID#/#ID#/');
	 * //$url = /folder/page/10/100
	 */
	static function getUrl($array, $url) {
		if (false !== ($pos = strpos($url, '?'))) {
			$query = substr($url, $pos);
			$url = substr($url, 0, $pos);
		} else {
			$query = null;
		}

		$url = trim($url, '\/');
		$repl = preg_split("/\//", $url);
		foreach ($repl as &$part) {
			if (false !== strpos($part, '#')) {
				if (isset($array[trim($part, '#')])) {
					$part = $array[trim($part, '#')];
				}
			}
		}

		$url = '/'.implode('/', $repl).($query ? $query : '');

		return $url;
	}

	static function getLangOptions($class) {
		//load lang file
		$localeId = $class.'_Locale';
		if (Ebx_Vars::has($localeId)) {
			return Ebx_Vars::get($localeId);
		} else {
			if (defined('EBX_LIB_PATH')) {
				$path = rtrim(EBX_LIB_PATH, '\/').'/';
				$locale = include($path.'.lang/'.LANGUAGE_ID.'/'.$class.'.php');
				Ebx_Vars::set($localeId, $locale);
				return Ebx_Vars::get($localeId);
			} else {
				trigger_error('Undefined Ebx path', E_USER_ERROR);
			}
		}
	}

	static function db2Array($dbResult, $method = null) {
		if (!is_object($dbResult)) {
			return array();
		}
		if (!is_string($method)) {
			$method = 'Fetch';
		}

		$result = array();
		while (false !== ($result[] = $dbResult->$method()));
		array_pop($result);

		return $result;
	}

	static function getQuery($add = null, $delete = null, $merge = true) {
		$query = Ebx_Http_Request::getInstance()->getQuery();
		if ($delete !== null) {
			if (!is_array($delete)) {
				$delete = (array)$delete;
			}
			$delete = array_flip($delete);
			$query = array_diff_key($query, $delete);
		}

		if (is_array($add)) {
			if ($merge) {
				$query = array_merge($query, $add);
			} else {
				$query = $add;
			}
		}

		return $query;
	}

	static function getHttpQuery($add = null, $delete = null, $merge = true) {
		$q = self::getQuery($add, $delete, $merge);
		return $q ? http_build_query($q) : '';
	}


}

?>